﻿Imports System.Linq.Expressions

Public Module QueryExtensions
    

    <System.Runtime.CompilerServices.Extension()> _
    Public Function SortBy(Of T)(ByVal source As IQueryable(Of T), ByVal propertyName As String) As IQueryable(Of T)

        If source Is Nothing Then


            Throw New ArgumentNullException("source")
        End If

        ' DataSource control passes the sort parameter with a direction

        ' if the direction is descending 

        Dim descIndex As Integer = propertyName.IndexOf(" DESC")

        If descIndex >= 0 Then


            propertyName = propertyName.Substring(0, descIndex).Trim()
        End If



        If [String].IsNullOrEmpty(propertyName) Then


            Return source
        End If



        Dim parameter As ParameterExpression = Expression.Parameter(source.ElementType, [String].Empty)

        Dim [property] As MemberExpression = Expression.[Property](parameter, propertyName)

        Dim lambda As LambdaExpression = Expression.Lambda([property], parameter)



        Dim methodName As String = If((descIndex < 0), "OrderBy", "OrderByDescending")





        Dim methodCallExpression As Expression = Expression.[Call](GetType(Queryable), methodName, New Type() {source.ElementType, [property].Type}, source.Expression, Expression.Quote(lambda))




        Return source.Provider.CreateQuery(Of T)(methodCallExpression)
    End Function

End Module
